package uk.ac.lkl.lpp.ui;

import java.awt.*;

import java.awt.event.*;
//import java.util.logging.Logger;

import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.JTextField;
import javax.swing.JEditorPane;
import javax.swing.JComboBox;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.BorderFactory;
import javax.swing.SpringLayout;
import javax.swing.SwingConstants;

//import javax.swing.JButton;
import javax.swing.event.ChangeListener;
import javax.swing.event.ChangeEvent;

import uk.ac.lkl.common.ui.SpringUtilities;

//import uk.ac.lkl.common.util.Property;
import uk.ac.lkl.common.util.ds.NotifyingList;
//import uk.ac.lkl.common.ui.SlidePanel;
import uk.ac.lkl.lpp.PedagogyPlan;

import uk.ac.lkl.lpp.model.PedagogyPlanModel;
import uk.ac.lkl.lpp.model.ldo.*;
import uk.ac.lkl.lpp.model.xml.ChunkPropertyNames;
//import javax.swing.*;

public class ChunkPropertyPanel extends JPanel  implements ChunkPropertyNames{
	private static final long serialVersionUID = 1L;
//	private static Logger logger = Logger.getLogger("ac.uk.lkl");
	
	public static final String TYPE_COMBO_PROPERTY    = TYPE_PROPERTY+".combo";
	public static final String T_UNITS_COMBO_PROPERTY = TIME_UNIT_PROPERTY+".combo";
	public static final String SUB_TYPE_COMBO_PROPERTY= SUB_TYPE_PROPERTY+".combo";

    
    public static final String HELP_EXTENSION = ".help";

    private PedagogyPlanModel model;

    JTextField  nameTF    = new JTextField(10);
    JTextField  idTF      = new JTextField(10);
    JEditorPane descEP    = new JEditorPane();
    JComboBox   typeCB    = Messages.getJCombo(TYPE_COMBO_PROPERTY);
    JTextField  creditTF  = new JTextField(3);
    JComboBox   tUnitsCB  = Messages.getJCombo(T_UNITS_COMBO_PROPERTY);
    JTextField  nSubsTF   = new JTextField(3);
    JComboBox   subsCB    = Messages.getJCombo(SUB_TYPE_COMBO_PROPERTY);
    JLabel[]    timeLs    = {new JLabel(" hours"),new JLabel(" hours"),new JLabel(" hours")};
    JTextField  contactTF = new JTextField(4);
    JTextField  studyTF   = new JTextField(4);
    JTextField  numStudTF = new JTextField(4);
    
    

    public ChunkPropertyPanel(PedagogyPlan plan) {
        model = plan.getModel();
        model.addChangeListener(new ChangeListener(){
        	public void stateChanged(ChangeEvent e) {
        		updateFields();
        	}
        });
        setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
        
        JPanel p = new JPanel(new SpringLayout());

        // name
        p.add(Messages.getJButton(NAME_PROPERTY,true));
        p.add(nameTF);
        
        // id
        p.add(Messages.getJButton(ID_PROPERTY,true));
        idTF.addFocusListener(new FocusListener() {
        	public void focusGained(FocusEvent e){}
        	public void focusLost(FocusEvent e){
        		model.setId(idTF.getText());
        	}        	
        });
        p.add(idTF);
        SpringUtilities.makeCompactGrid(p, 1, 4, 20, 10, 6, 20);
        add(p);
        
        // type, time unit and subtype
        p = new JPanel(new SpringLayout());
        p.add(new JLabel("A "));
        p.add(typeCB);
        p.add(new JLabel(" of "));
        p.add(creditTF);
        p.add(tUnitsCB);
        p.add(new JLabel(" consisting of "));
        p.add(nSubsTF);
        p.add(subsCB);
        
        SpringUtilities.makeCompactGrid(p, 1, 8, 20, 10, 6, 20);
        add(p);
        
        
        // description
        p = new JPanel(new SpringLayout());
        JButton jb = Messages.getJButton(DESCRIPTION_PROPERTY,true);
        jb.setHorizontalAlignment(SwingConstants.LEFT);
        p.add(jb);
        descEP.setEditable(true);
        descEP.setContentType("text/plain");
        descEP.setBackground(Color.WHITE);
        descEP.setBorder(BorderFactory.createEtchedBorder());
        p.add(descEP);

        SpringUtilities.makeCompactGrid(p, 2, 1, 5, 4, 6, 10);
        add(p);

        // times
        // | contact <units> | [] | Start date   | [] |
        // | study  <units>  | [] | Duration     | [] |
        // | no. of students | [] | no. of staff | [] |
        p = new JPanel(new SpringLayout());
        Box b = new Box(BoxLayout.X_AXIS);
        b.add(Messages.getJButton(CONTACT_TIME_PROPERTY,true));
        b.add(timeLs[1]);        
        p.add(b);
        p.add(contactTF);        
        p.add(Messages.getJButton(START_DATE_PROPERTY,true));
        JTextField tf = new JTextField();
        tf.setEnabled(false);
        p.add(tf);
        b = new Box(BoxLayout.X_AXIS);
        b.add(Messages.getJButton(STUDY_TIME_PROPERTY,true));
        b.add(timeLs[2]);
        p.add(b);
        p.add(studyTF);
        
        p.add(Messages.getJButton(DURATION_PROPERTY,true));
        tf = new JTextField();
        tf.setEnabled(false);
        p.add(tf);
        b = new Box(BoxLayout.X_AXIS);
        p.add(Messages.getJButton(NUM_STUD_PROPERTY,true));
        p.add(numStudTF);
        p.add(Messages.getJButton(NUM_STAFF_PROPERTY,true));
        tf = new JTextField();
        tf.setEnabled(false);
        p.add(tf);
        

        SpringUtilities.makeCompactGrid(p, 3, 4, 5, 4, 3, 3);
        add(p);

        updateFields();
        registerListeners();
        add(Box.createVerticalStrut(10));
        add(Box.createVerticalGlue());
    	// aims
    	NotifyingList<ModuleAim> aimList = (NotifyingList<ModuleAim>) model.getList(ModuleAim.class);    	
    	LEDrawer aimsDrawer = new LEDrawer(aimList,ModuleAim.class,"Aims");
		add(aimsDrawer);

    	// topics
		NotifyingList<Topic> topicList = (NotifyingList<Topic>) model.getList(Topic.class);
		LEDrawer topicDrawer = new LEDrawer(topicList,Topic.class,"Topics");
		this.add(topicDrawer);
    	
    	// outcomes
		NotifyingList<LearningOutcome> outcomesList = (NotifyingList<LearningOutcome>) model.getList(LearningOutcome.class);
		LEDrawer outcomeDrawer = new LEDrawer(outcomesList,LearningOutcome.class,"Outcomes");
		
		this.add(outcomeDrawer);
    }

    /**
     * called when we get a changeEvent from the model. need to refresh all fields.
     *
     */
    private void updateFields() {
        nameTF.setText(model.getName());
        idTF.setText(model.getId());
        descEP.setText(model.getDescription());
        typeCB.setSelectedItem(model.getType());
        creditTF.setText(String.valueOf(model.getCreditTime()));
        tUnitsCB.setSelectedItem(model.getTime_unit());
        nSubsTF.setText(String.valueOf(model.getNSubs()));
        subsCB.setSelectedItem(model.getSubType());
        contactTF.setText(String.valueOf(model.getContactTime()));
        studyTF.setText(String.valueOf(model.getStudyTime()));
        numStudTF.setText(String.valueOf(model.getNumStudents()));
        updateTimeLabels();
    }

    /**
     * register event listeners on all components.
     * just a stylistic convienence.
     */
    private void registerListeners() {
        nameTF.addFocusListener(new FocusAdapter() {
        	public void focusLost(FocusEvent e){
        		model.setName(nameTF.getText());
        	}        	
        });
        idTF.addFocusListener(new FocusAdapter() {
        	public void focusLost(FocusEvent e){
        		model.setId(idTF.getText());
        	}        	
        });
        descEP.addFocusListener(new FocusAdapter() {
        	public void focusLost(FocusEvent e){
        		model.setDescription(descEP.getText());
        	}        	
        });
        typeCB.addActionListener(new ActionListener(){
        	public void actionPerformed(ActionEvent e){
        		model.setType(typeCB.getSelectedItem().toString());
        	}
        });
        tUnitsCB.addActionListener(new ActionListener(){
        	public void actionPerformed(ActionEvent e){
        		model.setTime_unit(tUnitsCB.getSelectedItem().toString());
        	}
        });
        nSubsTF.addFocusListener(new FocusAdapter() {
        	public void focusLost(FocusEvent e){
        		try {
        			model.setNSubs(Integer.parseInt(nSubsTF.getText()));
        		} catch (NumberFormatException ex){
        			nSubsTF.setText(String.valueOf(model.getNSubs()));
        		}
        	}        	
        });
        subsCB.addActionListener(new ActionListener(){
        	public void actionPerformed(ActionEvent e){
        		model.setSubType(subsCB.getSelectedItem().toString());
        	}
        });
        creditTF.addFocusListener(new FocusAdapter() {
        	public void focusLost(FocusEvent e){
        		try {
        			model.setCreditTime(Integer.parseInt(creditTF.getText()));
        		} catch (NumberFormatException ex){
        			creditTF.setText(String.valueOf(model.getCreditTime()));
        		}
        	}        	
        });
        contactTF.addFocusListener(new FocusAdapter() {
        	public void focusLost(FocusEvent e){
        		try {
        			model.setContactTime(Integer.parseInt(contactTF.getText()));
        		} catch (NumberFormatException ex){
        			contactTF.setText(String.valueOf(model.getContactTime()));
        		}
        	}        	
        });
        studyTF.addFocusListener(new FocusAdapter() {
        	public void focusLost(FocusEvent e){
        		try {
        			model.setStudyTime(Integer.parseInt(studyTF.getText()));
        		} catch (NumberFormatException ex){
        			studyTF.setText(String.valueOf(model.getStudyTime()));
        		}
        	}        	
        });
        numStudTF.addFocusListener(new FocusAdapter() {
        	public void focusLost(FocusEvent e){
        		try {
        			model.setNumStudents(Integer.parseInt(numStudTF.getText()));
        		} catch (NumberFormatException ex){
        			numStudTF.setText(String.valueOf(model.getNumStudents()));
        		}
        	}        	
        });
    }

    
    private void updateTimeLabels() {
        for (int i=0; i<timeLs.length; i++) {
        	timeLs[i].setText(model.getTime_unit());
        }    	
    }
}
